package cn.com.infcn.monitor.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.alibaba.fastjson.JSON;

import cn.com.infcn.monitor.bean.IFCResponseBean;
import cn.com.infcn.monitor.bean.IFCResponseBeanMean;

public class IFCFileUtils {

	/**
	 * 判断文件夹是否存在，如果不存在则创建
	 */
	private static void createDirectory() {
		File file = new File(IFCMonitorConstanst.dataPath);
		// 如果文件夹不存在则创建
		if (!file.exists() && !file.isDirectory()) {
			file.mkdirs();// 创建多级目录
		}
	}

	/**
	 * 获取当前写入监控日志的文件
	 * 
	 * @return
	 */
	private static String getMonitorFile() {
		// 判断目录是否存在，如果不存在则创建
		createDirectory();

		String dateStr = IFCDateUtils.getDateStr(new Date(), "yyyyMMdd");

		String fileName = getMonitorFileName(dateStr);
		String filePath = IFCMonitorConstanst.dataPath + fileName;
		File file = new File(filePath);
		if (!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
			}
		}
		return filePath;
	}

	/**
	 * 监控日志写入文件
	 * 
	 * @param text
	 *            一行一条监控信息，统一使用"\n"换行符
	 * @throws Exception
	 */
	public synchronized static void writerMonitorInfo(String text) {
		// 获取要写入的日志文件
		String monitorFile = getMonitorFile();

		FileOutputStream fos = null;
		OutputStreamWriter osw = null;
		BufferedWriter writer = null;
		try {
			fos = new FileOutputStream(monitorFile, true);
			osw = new OutputStreamWriter(fos, "UTF-8");
			writer = new BufferedWriter(osw);

			writer.write(text + "\n");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (writer != null)
					writer.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if (osw != null)
					osw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if (fos != null)
					fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	/**
	 * 查询指定时间段直接的监控信息
	 * 
	 * @param startDate
	 *            开始日期 【格式：yyyyMMddHHmm】
	 * @param endDate
	 *            结束日期 【格式：yyyyMMddHHmm】
	 * @return
	 */
	public static String readerMonitorInfo(final String startDate, final String endDate, Set<String> typeSet, int interval) {
		String lines = "";

		String startDateStr = startDate.substring(0, 8);
		String endDateStr = endDate.substring(0, 8);

		// 获取查询监控日志之间的天数
		List<String> dayList = IFCDateUtils.getDaysBetween(startDateStr, endDateStr, "yyyyMMdd");

		if (dayList != null && dayList.size() > 0) {
			for (String day : dayList) {

				String fileName = getMonitorFileName(day);

				String filePath = IFCMonitorConstanst.dataPath + fileName;

				File file = new File(filePath);
				if (file.exists()) {
					long startDateLong = Long.parseLong(startDate);
					long endDateLong = Long.parseLong(endDate);

					FileInputStream fis = null;
					InputStreamReader isr = null;
					BufferedReader reader = null;
					try {
						fis = new FileInputStream(file);
						isr = new InputStreamReader(fis, "UTF-8");
						reader = new BufferedReader(isr);

						if(interval>1){
							lines += getLines(reader, startDateLong, endDateLong, typeSet, interval);
						}else{
							lines += getLines(reader, startDateLong, endDateLong, typeSet);
						}
					} catch (Exception e) {
						e.printStackTrace();
					} finally {
						try {
							if (reader != null)
								reader.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
						try {
							if (isr != null)
								isr.close();
						} catch (IOException e1) {
							e1.printStackTrace();
						}
						try {
							if (fis != null)
								fis.close();
						} catch (IOException e2) {
							e2.printStackTrace();
						}
					}
				}
			}
		}
		String resultJson = "";
		if (!lines.equals("")) {
			resultJson = "[" + lines.substring(0, lines.length() - 1) + "]";
		}
		return resultJson;
	}

	private static String getMonitorFileName(String yyyyMMdd) {
		return IFCMonitorConstanst.MONITOR_LOG_FILE_PREFIX + yyyyMMdd + ".log";
	}

	/**
	 * 获取指定时间范围内数据
	 * @param reader
	 * @param startDateLong
	 * @param endDateLong
	 * @param typeSet
	 * @return
	 * @throws Exception
	 */
	public static String getLines(BufferedReader reader, long startDateLong, long endDateLong, Set<String> typeSet) throws Exception {
		String lines = "";
		String line = "";
		while ((line = reader.readLine()) != null && line.length()>22) {
			
			String monitorDate = line.substring(9, 21);
			long monitorDateLong = 0l;
			try {
				monitorDateLong = Long.parseLong(monitorDate);
			} catch (Exception e) {
				continue;
			}
			if (startDateLong <= monitorDateLong && monitorDateLong <= endDateLong) {
				
				//判断是否有指定参数
				if(typeSet.size()>0){
					IFCResponseBean ifcResponseBean = JSON.parseObject(line, IFCResponseBean.class);
	
					IFCResponseBean result = new IFCResponseBean();
					result.setDate(ifcResponseBean.getDate());
	
					boolean flag = false;
					for (String t : typeSet) {
						if (MonitorType.CPU.getName().equals(t)) {
							result.setIfcCpus(ifcResponseBean.getIfcCpus());
							flag = true;
						}
	
						if (MonitorType.SYSMEM.getName().equals(t)) {
							result.setIfcMem(ifcResponseBean.getIfcMem());
							flag = true;
						}
	
						if (MonitorType.OS.getName().equals(t)) {
							result.setIfcOperatingSystem(ifcResponseBean.getIfcOperatingSystem());
							flag = true;
						}
	
						if (MonitorType.USER.getName().equals(t)) {
							result.setIfcUsers(ifcResponseBean.getIfcUsers());
							flag = true;
						}
	
						if (MonitorType.FILESYSTEM.getName().equals(t)) {
							result.setIfcFileSystems(ifcResponseBean.getIfcFileSystems());
							flag = true;
						}
	
						if (MonitorType.NET.getName().equals(t)) {
							result.setIfcNets(ifcResponseBean.getIfcNets());
							flag = true;
						}
	
						if (MonitorType.DIRECTORY.getName().equals(t)) {
							result.setIfcDirectorys(ifcResponseBean.getIfcDirectorys());
							flag = true;
						}
	
						if (MonitorType.JVMCLASSLOADING.getName().equals(t)) {
							result.setIfcJVMClassLoading(ifcResponseBean.getIfcJVMClassLoading());
							flag = true;
						}
	
						if (MonitorType.JVMCOMPILATION.getName().equals(t)) {
							result.setIfcJVMCompilation(ifcResponseBean.getIfcJVMCompilation());
							flag = true;
						}
	
						if (MonitorType.JVMGARBAGECOLLECTOR.getName().equals(t)) {
							result.setIfcJVMGarbageCollectors(ifcResponseBean.getIfcJVMGarbageCollectors());
							flag = true;
						}
	
						if (MonitorType.JVMMEMORYMANAGER.getName().equals(t)) {
							result.setIfcJVMMemoryManagers(ifcResponseBean.getIfcJVMMemoryManagers());
							flag = true;
						}
	
						if (MonitorType.JVMMEMORYPOOL.getName().equals(t)) {
							result.setIfcJVMMemoryPool(ifcResponseBean.getIfcJVMMemoryPool());
							flag = true;
						}
	
						if (MonitorType.JVMMEMORY.getName().equals(t)) {
							result.setIfcJVMMemory(ifcResponseBean.getIfcJVMMemory());
							flag = true;
						}
	
						if (MonitorType.JVMOPERATINGSYSTEM.getName().equals(t)) {
							result.setIfcJVMOperatingSystem(ifcResponseBean.getIfcJVMOperatingSystem());
							flag = true;
						}
	
						if (MonitorType.JVMRUNTIME.getName().equals(t)) {
							result.setIfcJVMRuntime(ifcResponseBean.getIfcJVMRuntime());
							flag = true;
						}
	
						if (MonitorType.JVMTHREAD.getName().equals(t)) {
							result.setIfcJVMThread(ifcResponseBean.getIfcJVMThread());
							flag = true;
						}
	
						if (MonitorType.HTTPREQUEST.getName().equals(t)) {
							result.setIfcHttpRequest(ifcResponseBean.getIfcHttpRequest());
							flag = true;
						}
	
						if (MonitorType.HTTPSESSION.getName().equals(t)) {
							result.setIfcHttpSession(ifcResponseBean.getIfcHttpSession());
							flag = true;
						}
					}
	
					if (flag) {
						line = JSON.toJSONString(result);
					}
				}
	
				lines += line + ",";
			}
		}
		return lines;
	}
	
	/**
	 * 获取指定时间范围内数据,并根据interval进行合并数据，求平均值
	 * @param reader
	 * @param startDateLong
	 * @param endDateLong
	 * @param typeSet
	 * @param interval
	 * @return
	 * @throws Exception
	 */
	public static String getLines(BufferedReader reader, long startDateLong, long endDateLong, Set<String> typeSet, int interval) throws Exception {
		
		String lines = "";
		String line = "";
		
		long nextDate = 0;
		
		IFCResponseBeanMean resultMean = null;
		
		while ((line = reader.readLine()) != null && line.length()>22) {
		
			String monitorDate = line.substring(9, 21);
			long monitorDateLong = 0l;
			try {
				monitorDateLong = Long.parseLong(monitorDate);
			} catch (Exception e) {
			}
			
			
			if (startDateLong <= monitorDateLong && monitorDateLong <= endDateLong) {
				
				//判断是否有指定参数
				if(typeSet.size()>0 ){
					IFCResponseBean ifcResponseBean = JSON.parseObject(line, IFCResponseBean.class);
	
					//第一次进入：获取下一次间隔的时间
					if(nextDate==0){
						long mod = monitorDateLong%interval;
						if(mod==0){
							nextDate = monitorDateLong;
						}else{
							nextDate = monitorDateLong+(interval-mod);
						}
						
						resultMean = new IFCResponseBeanMean();
						if(nextDate>endDateLong){
							resultMean.setDate(endDateLong+"");
						}else{
							resultMean.setDate(nextDate+"");
						}
					}
					
					//获取下一次间隔的时间
					if(monitorDateLong>nextDate){
						//获取这段时间内平均值
						IFCResponseBean jsonObj = resultMean.getIFCResponseBean();
						line = JSON.toJSONString(jsonObj);
						lines += line + ",";
						
						while(monitorDateLong>nextDate){
							nextDate = nextDate+interval;
							resultMean = new IFCResponseBeanMean();
							if(nextDate>endDateLong){
								resultMean.setDate(endDateLong+"");
							}else{
								resultMean.setDate(nextDate+"");
							}
						}
					}
	
					for (String t : typeSet) {
						if (MonitorType.CPU.getName().equals(t)) {
							resultMean.addIFCCpu(ifcResponseBean.getIfcCpus());
						}
	
						if (MonitorType.SYSMEM.getName().equals(t)) {
							resultMean.addIFCMemCount(ifcResponseBean.getIfcMem());
						}
	
						if (MonitorType.JVMOPERATINGSYSTEM.getName().equals(t)) {
							resultMean.addIFCJVMOperatingSystemCount(ifcResponseBean.getIfcJVMOperatingSystem());
						}
	
					}
	
				}
	
			}
		}
		
		//获取这段时间内平均值
		if(resultMean!=null){
			IFCResponseBean jsonObj = resultMean.getIFCResponseBean();
			line = JSON.toJSONString(jsonObj);
			lines += line + ",";
		}
		
		return lines;
	}

	public static String correctPath(String path) {
		if (path == null) {
			return null;
		}
		path = path.replace("\\", File.separator);
		path = path.replace("/", File.separator);
		return path;
	}

	public static void main(String[] args) throws Exception {
		// writerMonitorInfo("33");
		IFCMonitorConstanst.dataPath = "D:" + File.separator + "data" + File.separator;
		Set<String> typeSet = new HashSet<String>();
		typeSet.add("cpu");
//		String result = readerMonitorInfo("2016092111", "201609090020", typeSet);
//		System.out.println(result);
		// IFCMonitorConstanst.dataPath = "D:" + File.separator + "hello.txt";
		// createDirectory();

		// String[] a = new String[]{"aa","bb"};
		// String json = JSON.toJSONString(a);
		// System.out.println(json);
	}
}
